package inl.resilienceManager.qmul.gemom;

import java.util.HashMap;
import java.util.Vector;

import resilienceManager.qmul.gemom.NSitem;


/** 
 * COPYRIGHT DISCLAIMER
 * Synopsis: All the source codes presented in this document are intellectual
 * properties of Queen Mary, University of London.
 * 
 * @year 2010
 * @author Peng Jiang, John Bigham, Jiayi Wu Jinfu Wang------------QMUL
 * @version 1.0 
 */

public class VarianceCalculation {
	
	/**
	 * static method used for the variance calculation for an item
	 * 
	 *@param dataTable: float[][], the variance table for all namespace
	 *@param item: NSitem, the item
	 *
	 * **/
	
	private static float[][] vcovMatrix=(TableSaver.loadMatrix()); 
	private static HashMap<String, String> nsmean = TableSaver.getMapNSMean();
//	private static float[][] vcovMatrix=TableSaver.OtoF(TableSaver.Loading()); 

	
	public static float sumVar(float[][] dataTable, NSitem item )
	{
		float sumVariance=0;
		
		Vector<Integer> nslist= item.getNSlist();
		
		int[] nsArray= new int[nslist.size()];
		
		// sum of the variance
		for(int i=0; i< nslist.size(); i++)
		{
//			nsArray contains the ns numbers of 'item' 
//			var(ns_i)+var(ns_j)
			nsArray[i]= nslist.get(i).intValue();
//XXX array out of bound problem		
			sumVariance=sumVariance+dataTable[nsArray[i]-1][nsArray[i]-1];
//			System.out.println(dataTable);
		}
		
		
		// sum of the convariance
//		2 var(ns_i, ns_j)
		for(int i=0; i< nslist.size()-1; i++)
		{
			for(int j=i+1; j<nslist.size(); j++)
				
				sumVariance=sumVariance+ 2* dataTable[nsArray[i]-1][nsArray[j]-1];
			
		}
		
		
		
		return sumVariance;
	}
	
	
	/**
	 * static method used for the convariance of two items
	 * 
	 * 
	 * @param dataTable: float[][], the variance table for all namespace
	 * @param items1: NSitems
	 * @param items1: NSitems
	 * **/
	
	public static float ConVarItem(float[][] dataTable,NSitem item1, NSitem item2){
//		FIXME dead loop here?
		float conVariance=0;
		
		Vector<Integer> nslist1= item1.getNSlist();
		int[] nsArray1= new int[nslist1.size()];
		
		Vector<Integer> nslist2= item2.getNSlist();
		int[] nsArray2= new int[nslist2.size()];
		
		for(int i=0; i< nslist1.size(); i++)
		{
			nsArray1[i]= nslist1.get(i).intValue();
			for(int j=0; j<nslist2.size(); j++)
			{
				nsArray2[j]=nslist2.get(j).intValue();
				
				conVariance=conVariance+dataTable[nsArray1[i]-1][nsArray2[j]-1];
			}
		}
		
		
		return conVariance;
		
	}
	
	
	
	/**
	 * static method used for the variance calculation for combination of items
	 * 
	 * @param dataTable: float[][], the variance table for all namespace
	 * @param items: NSitems[], the combination of items
	 * 
	 * **/
	public static float sumItem(NSitem[] items)
	{
		
//		float[][] dataTable=TableSaver.OtoF(TableSaver.Loading()); 
		float[][] dataTable= vcovMatrix; 
		
		float sumVariance=0;
//		FIXME return 0 if items is null or empty
		if(items==null || items.length==0){
			return 0;
		}
		for(int i=0; i<items.length; i++)
		{
			
			sumVariance=sumVariance+sumVar(dataTable,items[i]);
			
		}
		
		for(int i=0; i<items.length-1; i++)
		{
			for(int j=i+1; j<items.length; j++)
			{
				sumVariance=sumVariance+ConVarItem(dataTable, items[i], items[j]);
			}
		}
		return sumVariance;
	}


	public static double sumMean(NSitem[] items) {
		double mean = 0;
		for (NSitem item: items){
			Vector<Integer> nss = item.getNSlist();
			for (Integer ns : nss){
				mean=mean+Double.parseDouble(nsmean.get(""+ns.intValue()));
			}
		}
		return mean;
	}

}
